
#include "cg_local.h"

int CG_DrawField (int x, int y, int width, int value, int charWidth, int charHeight, qboolean dodrawpic, qboolean leftAlign );		// NERVE - SMF

/*void CG_FitTextToWidth( char* instr, int w, int size) {
	char buffer[1024];
	char	*s, *p, *c, *ls;
	int		l;
	
	strcpy(buffer, instr);
	memset(instr, 0, size);

	c = s = instr;
	p = buffer;
	ls = NULL;
	l = 0;
	while(*p) {
		*c = *p++;
		l++;

		if(*c == ' ') {
			ls = c;
		} // store last space, to try not to break mid word

		c++;

		if(*p == '\n') {
			s = c+1;
			l = 0;
		} else if(l > w) {
			if(ls) {
				*ls = '\n';
				l = strlen(ls+1);
			} else {
				*c = *(c-1);
				*(c-1) = '\n';
				s = c++;
				l = 0;
			}

			ls = NULL;
		}
	}

	if(c != buffer && (*(c-1) != '\n')) {
		*c++ = '\n';
	}
	
	*c = '\0';
}*/

int CG_TrimLeftPixels( char* instr, float scale, float w, int size) {
	char buffer[1024];
	char *p, *s;
	int tw;
	int i;

	Q_strncpyz(buffer, instr, 1024);
	memset(instr, 0, size);

	for( i = 0, p = buffer; *p; p++, i++) {
		instr[i] = *p;
		tw = CG_Text_Width( instr, scale, 0 );
		if(tw >= w) {
			memset(instr, 0, size);
			for(s = instr, p = &buffer[i+1]; *p && ((s - instr) < size); p++, s++) {
				*s = *p;
			}
			return tw - w;
		}
	}

	return -1;
}


void CG_FitTextToWidth_Ext( char* instr, float scale, float w, int size, fontInfo_t* font ) {
	char buffer[1024];
	char	*s, *p, *c, *ls;
	int		l;
	
	Q_strncpyz(buffer, instr, 1024);
	memset(instr, 0, size);

	c = s = instr;
	p = buffer;
	ls = NULL;
	l = 0;
	while(*p) {
		*c = *p++;
		l++;

		if(*c == ' ') {
			ls = c;
		} // store last space, to try not to break mid word

		c++;

		if(*p == '\n') {
			s = c+1;
			l = 0;
		} else if(CG_Text_Width_Ext( s, scale, 0, font ) > w) {
			if(ls) {
				*ls = '\n';
				s = ls+1;
			} else {
				*c = *(c-1);
				*(c-1) = '\n';
				s = c++;
			}

			ls = NULL;
			l = 0;
		}
	}

	if(c != buffer && (*(c-1) != '\n')) {
		*c++ = '\n';
	}
	
	*c = '\0';
}

void CG_FitTextToWidth2( char* instr, float scale, float w, int size ) {
	char buffer[1024];
	char	*s, *p, *c, *ls;
	int		l;
	
	Q_strncpyz(buffer, instr, 1024);
	memset(instr, 0, size);

	c = s = instr;
	p = buffer;
	ls = NULL;
	l = 0;
	while(*p) {
		*c = *p++;
		l++;

		if(*c == ' ') {
			ls = c;
		} // store last space, to try not to break mid word

		c++;

		if(*p == '\n') {
			s = c+1;
			l = 0;
		} else if(CG_Text_Width( s, scale, 0 ) > w) {
			if(ls) {
				*ls = '\n';
				s = ls+1;
			} else {
				*c = *(c-1);
				*(c-1) = '\n';
				s = c++;
			}

			ls = NULL;
			l = 0;
		}
	}

	if(c != buffer && (*(c-1) != '\n')) {
		*c++ = '\n';
	}
	
	*c = '\0';
}

void CG_FitTextToWidth_SingleLine( char* instr, float scale, float w, int size) {
	char	*s, *p;
	char	buffer[1024];

	Q_strncpyz(buffer, instr, 1024);
	memset(instr, 0, size);
	p = instr;
	
	for( s = buffer; *s; s++, p++ ) {
		*p = *s;
		if(CG_Text_Width( instr, scale, 0 ) > w) {
			*p = '\0';
			return;
		}
	}
}

/*
==============
weapIconDrawSize
==============
*/
static int weapIconDrawSize(int weap) {
	switch(weap) {

		// weapons to not draw
//		case WP_KNIFE:
//			return 0;

		// weapons with 'wide' icons
		case WP_THOMPSON:
		case WP_MP40:
		case WP_STEN:
		case WP_PANZERFAUST:
		case WP_FLAMETHROWER:
//		case WP_SPEARGUN:
		case WP_GARAND:
		case WP_FG42:
		case WP_FG42SCOPE:
		case WP_KAR98:
		case WP_GPG40:
		case WP_CARBINE:
		case WP_M7:
		case WP_MOBILE_MG42:
		case WP_MOBILE_MG42_SET:
		case WP_K43:
		case WP_GARAND_SCOPE:
		case WP_K43_SCOPE:
		case WP_MORTAR:
		case WP_MORTAR_SET:
			return 2;
	}

	return 1;
}


/*
==============
CG_DrawPlayerWeaponIcon
==============
*/
void CG_DrawPlayerWeaponIcon( rectDef_t *rect, qboolean drawHighlighted, int align, vec4_t *refcolor ) {
	int			size;
	int			realweap;			// DHM - Nerve
	qhandle_t	icon;
	float		scale,halfScale;
	vec4_t		hcolor;
	
	VectorCopy(*refcolor, hcolor);
	hcolor[3] = 1.f;

	if( cg.predictedPlayerEntity.currentState.eFlags & EF_MG42_ACTIVE ||
		cg.predictedPlayerEntity.currentState.eFlags & EF_MOUNTEDTANK )
		realweap = WP_MOBILE_MG42;
	else
		realweap = cg.predictedPlayerState.weapon;

	size = weapIconDrawSize(realweap);

	if(!size)
		return;

	if( cg.predictedPlayerEntity.currentState.eFlags & EF_MOUNTEDTANK && cg_entities[cg_entities[ cg_entities[ cg.snap->ps.clientNum ].tagParent ].tankparent].currentState.density & 8 ) {
		icon = cgs.media.browningIcon;
	} else {
		if( drawHighlighted ) {
			//icon = cg_weapons[ realweap ].weaponIcon[1];
			icon = cg_weapons[ realweap ].weaponIcon[1];	// we don't have icon[0];
		} else {
			icon = cg_weapons[ realweap ].weaponIcon[1];
		}
	}



	// pulsing grenade icon to help the player 'count' in their head
	if(cg.predictedPlayerState.grenadeTimeLeft) {	// grenades and dynamite set this

		// these time differently 
		if( realweap == WP_DYNAMITE ) {
			if(((cg.grenLastTime)%1000)>((cg.predictedPlayerState.grenadeTimeLeft)%1000)) {
				trap_S_StartLocalSound(cgs.media.grenadePulseSound4, CHAN_LOCAL_SOUND );
			}
		} else {
			if(((cg.grenLastTime)%1000)<((cg.predictedPlayerState.grenadeTimeLeft)%1000)) {
				switch( cg.predictedPlayerState.grenadeTimeLeft/1000) {
					case 3:
						trap_S_StartLocalSound(cgs.media.grenadePulseSound4, CHAN_LOCAL_SOUND );
						break;
					case 2:
						trap_S_StartLocalSound(cgs.media.grenadePulseSound3, CHAN_LOCAL_SOUND );
						break;
					case 1:
						trap_S_StartLocalSound(cgs.media.grenadePulseSound2, CHAN_LOCAL_SOUND );
						break;
					case 0:
						trap_S_StartLocalSound(cgs.media.grenadePulseSound1, CHAN_LOCAL_SOUND );
						break;
				}
			}
		}

		scale = (float)((cg.predictedPlayerState.grenadeTimeLeft)%1000) / 100.0f;
		halfScale = scale * 0.5f;

		cg.grenLastTime = cg.predictedPlayerState.grenadeTimeLeft;
	}
	else {
		scale = halfScale = 0;
	}


	if ( icon ) {
		float x, y, w, h;

		if(size == 1) {	// draw half width to match the icon asset

			// start at left
			x = rect->x - halfScale;
			y = rect->y - halfScale;
			w = rect->w/2 + scale;
			h = rect->h + scale;

			switch(align) {
				case ITEM_ALIGN_CENTER:
					x += rect->w/4;
					break;
				case ITEM_ALIGN_RIGHT:
					x += rect->w/2;
					break;
				case ITEM_ALIGN_LEFT:
				default:
					break;
			}

		} else {
			x = rect->x - halfScale;
			y = rect->y - halfScale;
			w = rect->w + scale;
			h = rect->h + scale;
		}


		trap_R_SetColor( hcolor ); // JPW NERVE
		CG_DrawPic( x, y, w, h, icon );
	}
}

#define CURSORHINT_SCALE	10

/*
==============
CG_DrawCursorHints

  cg_cursorHints.integer == 
	0:	no hints
	1:	sin size pulse
	2:	one way size pulse
	3:	alpha pulse
	4+:	static image

==============
*/
void CG_DrawCursorhint(rectDef_t *rect) {
	float		*color;
	qhandle_t	icon, icon2 = 0;
	float		scale, halfscale;
	//qboolean	redbar = qfalse;
	qboolean	yellowbar = qfalse;

	if(!cg_cursorHints.integer)
		return;

	CG_CheckForCursorHints();

	switch(cg.cursorHintIcon) {

		case HINT_NONE:
		case HINT_FORCENONE:
			icon = 0;
			break;
		case HINT_DOOR:
			icon = cgs.media.doorHintShader;
			break;
		case HINT_DOOR_ROTATING:
			icon = cgs.media.doorRotateHintShader;
			break;
		case HINT_DOOR_LOCKED:
			icon = cgs.media.doorLockHintShader;
			break;
		case HINT_DOOR_ROTATING_LOCKED:
			icon = cgs.media.doorRotateLockHintShader;
			break;
		case HINT_MG42:
			icon = cgs.media.mg42HintShader;
			break;
		case HINT_BREAKABLE:
			icon = cgs.media.breakableHintShader;
			break;
		case HINT_BREAKABLE_DYNAMITE:
			icon = cgs.media.dynamiteHintShader;
			break;
		case HINT_TANK:
			icon = cgs.media.tankHintShader;
			break;
		case HINT_SATCHELCHARGE:
			icon = cgs.media.satchelchargeHintShader;
			break;
		case HINT_CONSTRUCTIBLE:
			icon = cgs.media.buildHintShader;
			break;
		case HINT_UNIFORM:
			icon = cgs.media.uniformHintShader;
			break;
		case HINT_LANDMINE:
			icon = cgs.media.landmineHintShader;
			break;
		case HINT_CHAIR:
			icon = cgs.media.notUsableHintShader;

			// only show 'pickupable' if you're not armed, or are armed with a single handed weapon

			// rain - WEAPS_ONE_HANDED isn't valid anymore, because
			// WP_SILENCED_COLT uses a bit >31 (and, therefore, is too large
			// to be shifted in the way WEAPS_ONE_HANDED does on a 32-bit
			// system.) If you want to use HINT_CHAIR, you'll need to fix
			// this.
#if 0
			if( !(cg.predictedPlayerState.weapon) ||
				WEAPS_ONE_HANDED & (1<<(cg.predictedPlayerState.weapon))
				)
			{
				icon = cgs.media.chairHintShader;
			}
#endif
			break;
		case HINT_ALARM:
			icon = cgs.media.alarmHintShader;
			break;
		case HINT_HEALTH:
			icon = cgs.media.healthHintShader;
			break;
		case HINT_TREASURE:
			icon = cgs.media.treasureHintShader;
			break;
		case HINT_KNIFE:
			icon = cgs.media.knifeHintShader;
			break;
		case HINT_LADDER:
			icon = cgs.media.ladderHintShader;
			break;
		case HINT_BUTTON:
			icon = cgs.media.buttonHintShader;
			break;
		case HINT_WATER:
			icon = cgs.media.waterHintShader;
			break;
		case HINT_CAUTION:
			icon = cgs.media.cautionHintShader;
			break;
		case HINT_DANGER:
			icon = cgs.media.dangerHintShader;
			break;
		case HINT_SECRET:
			icon = cgs.media.secretHintShader;
			break;
		case HINT_QUESTION:
			icon = cgs.media.qeustionHintShader;
			break;
		case HINT_EXCLAMATION:
			icon = cgs.media.exclamationHintShader;
			break;
		case HINT_CLIPBOARD:
			icon = cgs.media.clipboardHintShader;
			break;
		case HINT_WEAPON:
			icon = cgs.media.weaponHintShader;
			break;
		case HINT_AMMO:
			icon = cgs.media.ammoHintShader;
			break;
		case HINT_ARMOR:
			icon = cgs.media.armorHintShader;
			break;
		case HINT_POWERUP:
			icon = cgs.media.powerupHintShader;
			break;
		case HINT_HOLDABLE:
			icon = cgs.media.holdableHintShader;
			break;
		case HINT_INVENTORY:
			icon = cgs.media.inventoryHintShader;
			break;
		case HINT_PLYR_FRIEND:
			icon = cgs.media.hintPlrFriendShader;
			break;
		case HINT_PLYR_NEUTRAL:
			icon = cgs.media.hintPlrNeutralShader;
			break;
		case HINT_PLYR_ENEMY:
			icon = cgs.media.hintPlrEnemyShader;
			break;
		case HINT_PLYR_UNKNOWN:
			icon = cgs.media.hintPlrUnknownShader;
			break;

		// DHM - Nerve :: multiplayer hints
		case HINT_BUILD:
			icon = cgs.media.buildHintShader;
			break;
		case HINT_DISARM:
			icon = cgs.media.disarmHintShader;
			break;
		case HINT_REVIVE:
			icon = cgs.media.reviveHintShader;
			break;
		case HINT_DYNAMITE:
			icon = cgs.media.dynamiteHintShader;
			break;
		// dhm - end

		// Mad Doc - TDF
		case HINT_LOCKPICK:
			icon = cgs.media.doorLockHintShader;		// TAT 1/30/2003 - use the locked door hint cursor
			yellowbar = qtrue;	// draw the status bar in yellow so it shows up better
			break;

		case HINT_ACTIVATE:
		case HINT_PLAYER:
		default:
			icon = cgs.media.usableHintShader;
			break;
	}


	if(!icon)
		return;


	// color
	color = CG_FadeColor( cg.cursorHintTime, cg.cursorHintFade );
	if ( !color ) {
		trap_R_SetColor( NULL );
		return;
	}

	if(cg_cursorHints.integer == 3) {
		color[3] *= 0.5+0.5*sin((float)cg.time/150.0);
	}


	// size
	if(cg_cursorHints.integer >= 3) {	// no size pulsing
		scale = halfscale = 0;
	} else {
		if(cg_cursorHints.integer == 2)
			scale = (float)((cg.cursorHintTime)%1000) / 100.0f;	// one way size pulse
		else
			scale = CURSORHINT_SCALE * (0.5+0.5*sin((float)cg.time/150.0));	// sin pulse

		halfscale = scale * 0.5f;
	}

	// set color and draw the hint
	trap_R_SetColor( color );
	CG_DrawPic( rect->x - halfscale, rect->y - halfscale, rect->w + scale, rect->h + scale, icon );

	if( icon2 ) {
		CG_DrawPic( rect->x - halfscale, rect->y - halfscale, rect->w + scale, rect->h + scale, icon2 );
	}

	trap_R_SetColor( NULL );

	// draw status bar under the cursor hint
	if(cg.cursorHintValue) {
		if (yellowbar) {
			Vector4Set(color, 1, 1, 0, 1.0f);
		} else {
			Vector4Set(color, 0, 0, 1, 0.5f);
		}
		CG_FilledBar(rect->x, rect->y + rect->h + 4, rect->w, 8, color, NULL, NULL, (float)cg.cursorHintValue/255.0f, 0);
	}

}

float CG_GetValue(int ownerDraw, int type) {
	switch (ownerDraw) {
		default:
			break;
	}
	return -1;
}

qboolean CG_OtherTeamHasFlag() {
	return qfalse;
}

qboolean CG_YourTeamHasFlag() {
	return qfalse;
}

// THINKABOUTME: should these be exclusive or inclusive.. 
// 
qboolean CG_OwnerDrawVisible(int flags) {
	return qfalse;
}

#define PIC_WIDTH 12

/*
==============
CG_DrawWeapStability
	draw a bar showing current stability level (0-255), max at current weapon/ability, and 'perfect' reference mark

	probably only drawn for scoped weapons
==============
*/
void CG_DrawWeapStability( rectDef_t *rect ) {
	vec4_t goodColor = {0, 1, 0, 0.5f}, badColor = {1, 0, 0, 0.5f};

	if(!cg_drawSpreadScale.integer)
		return;

	if( cg_drawSpreadScale.integer == 1 && !BG_IsScopedWeapon( cg.predictedPlayerState.weapon ) ) {
		// cg_drawSpreadScale of '1' means only draw for scoped weapons, '2' means draw all the time (for debugging)
		return;
	}

	if( cg.predictedPlayerState.weaponstate != WEAPON_READY ) {
		return;
	}

	if(!(cg.snap->ps.aimSpreadScale)) {
		return;
	}

	if( cg.renderingThirdPerson ) {
		return;
	}

	CG_FilledBar(rect->x, rect->y, rect->w, rect->h, goodColor, badColor, NULL, (float)cg.snap->ps.aimSpreadScale / 255.0f, 2|4|256); // flags (BAR_CENTER|BAR_VERT|BAR_LERP_COLOR)
}


/*
==============
CG_DrawWeapHeat
==============
*/
void CG_DrawWeapHeat(rectDef_t *rect, int align) {
	vec4_t	color = {1, 0, 0, 0.2f}, color2 = {1, 0, 0, 0.5f};
	int flags = 0;

	if(!(cg.snap->ps.curWeapHeat))
		return;

	if( align != HUD_HORIZONTAL ) {
		flags|=4;	// BAR_VERT
	}

	flags|=1;		// BAR_LEFT			- this is hardcoded now, but will be decided by the menu script
	flags|=16;		// BAR_BG			- draw the filled contrast box
//	flags|=32;		// BAR_BGSPACING_X0Y5	- different style

	flags|=256;		// BAR_COLOR_LERP

	CG_FilledBar(rect->x, rect->y, rect->w, rect->h, color, color2, NULL, (float)cg.snap->ps.curWeapHeat / 255.0f, flags);
}

/*
==============
CG_OwnerDraw
==============
*/
void CG_OwnerDraw(float x, float y, float w, float h, float text_x, float text_y, int ownerDraw, int ownerDrawFlags, int align, float special, float scale, vec4_t color, qhandle_t shader, int textStyle) {
	rectDef_t rect;

	if( cg_drawStatus.integer == 0 ) {
		return;
	}

	rect.x = x;
	rect.y = y;
	rect.w = w;
	rect.h = h;

	switch (ownerDraw) {
	default:
		break;
	}
}

void CG_MouseEvent(int x, int y) {
	switch( cgs.eventHandling ) {
		case CGAME_EVENT_SPEAKEREDITOR:
		case CGAME_EVENT_GAMEVIEW:
		case CGAME_EVENT_CAMPAIGNBREIFING:
		case CGAME_EVENT_FIRETEAMMSG:
			cgs.cursorX += x;
			if( cgs.cursorX < 0 ) {
				cgs.cursorX = 0;
			} else if( cgs.cursorX > 640 ) {
				cgs.cursorX = 640;
			}

			cgs.cursorY += y;
			if( cgs.cursorY < 0 ) {
				cgs.cursorY = 0;
			} else if( cgs.cursorY > 480 ) {
				cgs.cursorY = 480;
			}

			if( cgs.eventHandling == CGAME_EVENT_SPEAKEREDITOR ) {
				CG_SpeakerEditorMouseMove_Handling( x, y );
			}

			break;
		case CGAME_EVENT_DEMO:
			cgs.cursorX += x;
			if( cgs.cursorX < 0 ) {
				cgs.cursorX = 0;
			} else if( cgs.cursorX > 640 ) {
				cgs.cursorX = 640;
			}

			cgs.cursorY += y;
			if( cgs.cursorY < 0 ) {
				cgs.cursorY = 0;
			} else if( cgs.cursorY > 480 ) {
				cgs.cursorY = 480;
			}

			if( x != 0 || y != 0 ) {
				cgs.cursorUpdate = cg.time + 5000;
			}
			break;


		default:
			if( cg.snap->ps.pm_type == PM_INTERMISSION ) {
				CG_Debriefing_MouseEvent( x, y );
				return;
			}

			// default handling
			if ( (cg.predictedPlayerState.pm_type == PM_NORMAL ||
				cg.predictedPlayerState.pm_type == PM_SPECTATOR) &&
				cg.showScores == qfalse ) {
				trap_Key_SetCatcher( trap_Key_GetCatcher() & ~KEYCATCH_CGAME );
				return;
			}
			break;
	}
}

/*
==================
CG_EventHandling
==================
*/
void CG_EventHandling( int type, qboolean fForced )
{
	if( cg.demoPlayback && type == CGAME_EVENT_NONE && !fForced ) {
		type = CGAME_EVENT_DEMO;
	}

	if( type != CGAME_EVENT_NONE ) {
		trap_Cvar_Set( "cl_bypassMouseInput", 0 );
	}

	switch( type ) {
		// OSP - Demo support
		case CGAME_EVENT_DEMO:
			cgs.fResize = qfalse;
			cgs.fSelect = qfalse;
			cgs.cursorUpdate = cg.time + 10000;
			cgs.timescaleUpdate = cg.time + 4000;
			CG_ScoresUp_f();
			break;

		case CGAME_EVENT_SPEAKEREDITOR:
		case CGAME_EVENT_GAMEVIEW:
		case CGAME_EVENT_NONE:
		case CGAME_EVENT_CAMPAIGNBREIFING:
		case CGAME_EVENT_FIRETEAMMSG:
		default:
			// default handling (cleanup mostly)
			if( cgs.eventHandling == CGAME_EVENT_GAMEVIEW ) {
				cg.showGameView = qfalse;
				trap_S_FadeBackgroundTrack( 0.0f, 500, 0 );

				trap_S_StopStreamingSound( -1 );
				cg.limboEndCinematicTime = 0;

				if( fForced ) {
					if( cgs.limboLoadoutModified ) {
						trap_SendClientCommand( "rs" );

						cgs.limboLoadoutSelected = qfalse;
					}
				}
			} else if( cgs.eventHandling == CGAME_EVENT_SPEAKEREDITOR ) {
				if( type == -CGAME_EVENT_SPEAKEREDITOR ) {
					type = CGAME_EVENT_NONE;
				} else {
					trap_Key_SetCatcher( KEYCATCH_CGAME );
					return;
				}
			} else if( cgs.eventHandling == CGAME_EVENT_CAMPAIGNBREIFING ) {
				type = CGAME_EVENT_GAMEVIEW;
			} else if( cgs.eventHandling == CGAME_EVENT_FIRETEAMMSG ) {
				cg.showFireteamMenu = qfalse;								
				trap_Cvar_Set( "cl_bypassmouseinput", "0" );
			} else if( cg.snap && cg.snap->ps.pm_type == PM_INTERMISSION && fForced ) {
				trap_UI_Popup( UIMENU_INGAME );
			}


			break;
	}


	cgs.eventHandling = type;

	if(type == CGAME_EVENT_NONE) {
		trap_Key_SetCatcher(trap_Key_GetCatcher() & ~KEYCATCH_CGAME);
		ccInitial = qfalse;
		if(cg.demoPlayback && cg.demohelpWindow != SHOW_OFF) {
			CG_ShowHelp_Off(&cg.demohelpWindow);
		}
	} else if( type == CGAME_EVENT_GAMEVIEW ) {
		cg.showGameView = qtrue;
		CG_LimboPanel_Setup();
		trap_Key_SetCatcher(KEYCATCH_CGAME);
	} else if( type == CGAME_EVENT_FIRETEAMMSG ) {
		cgs.ftMenuPos = -1;
		cgs.ftMenuMode = 0;
		cg.showFireteamMenu = qtrue;
		trap_Cvar_Set( "cl_bypassmouseinput", "1" );
		trap_Key_SetCatcher(KEYCATCH_CGAME);
	} else {
		trap_Key_SetCatcher(KEYCATCH_CGAME);
	}
}

void CG_KeyEvent(int key, qboolean down) {
	switch(cgs.eventHandling) {
		// Demos get their own keys
		case CGAME_EVENT_DEMO:
			CG_DemoClick(key, down);
			return;

		case CGAME_EVENT_CAMPAIGNBREIFING:
			CG_LoadPanel_KeyHandling( key, down );
			break;

		case CGAME_EVENT_FIRETEAMMSG:
			CG_Fireteams_KeyHandling( key, down );
			break;

		case CGAME_EVENT_GAMEVIEW:
			CG_LimboPanel_KeyHandling( key, down );
			break;

		case CGAME_EVENT_SPEAKEREDITOR:
			CG_SpeakerEditor_KeyHandling( key, down );
			break;

		default:
			if( cg.snap->ps.pm_type == PM_INTERMISSION ) {
				CG_Debriefing_KeyEvent( key, down );
				return;
			}

			// default handling
			if( !down ) {
				return;
			}

			if ( ( cg.predictedPlayerState.pm_type == PM_NORMAL ||
				(cg.predictedPlayerState.pm_type == PM_SPECTATOR && cg.showScores == qfalse))) {

				CG_EventHandling(CGAME_EVENT_NONE, qfalse);
				return;
			}
			break;
	}
}

int CG_ClientNumFromName(const char *p) {
	int i;
	for (i = 0; i < cgs.maxclients; i++) {
		if (cgs.clientinfo[i].infoValid && Q_stricmp(cgs.clientinfo[i].name, p) == 0) {
			return i;
		}
	}
	return -1;
}

void CG_GetTeamColor(vec4_t *color) {
	if( cg.snap->ps.persistant[PERS_TEAM] == TEAM_AXIS ) {
		(*color)[0] = 1;
		(*color)[3] = .25f;
		(*color)[1] = (*color)[2] = 0;
	} else if (cg.snap->ps.persistant[PERS_TEAM] == TEAM_ALLIES) {
		(*color)[0] = (*color)[1] = 0;
		(*color)[2] = 1;
		(*color)[3] = .25f;
	} else {
		(*color)[0] = (*color)[2] = 0;
		(*color)[1] = .17f;
		(*color)[3] = .25f;
	}
}

void CG_RunMenuScript( char **args ) {
}
